package model;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import util.LogTable;
import util.Name;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.mysql.jdbc.PreparedStatement;

import dao.Database;

public class QueryRec {
	
	
	/**Recommend top K queries 
	 * */
	
	
	
	public JsonObject initRec(int k,LogTable logtable){
		
		Map<String,Integer> opCountMap =  logtable.opCountMap;
	
		
		String level0 = "level0";
		String country = "country";
		String year = "year";
		
		ArrayList <String> resList = new ArrayList<String>();
		//Map<String,Integer> pMap = new HashMap<String,Integer>();  
		
		for(Map.Entry<String, Integer> entry : opCountMap.entrySet()){
			String key = entry.getKey();
			
			if(key.contains(level0)||key.contains(country)||key.contains(year)){
				if(resList.size()<k){
					resList.add(key);
				}
				else{
					for(int i= 0;i<resList.size();i++){
						if(entry.getValue()> opCountMap.get(resList.get(i))){
							resList.set(i, key);
							break;
						}
					}
				}
			}
		}
		
		JsonArray resArray = new JsonArray();
		JsonObject ret = new JsonObject();
		resList = modifyReclist(resList,logtable);
		
		for(String op : resList){
			resArray.add(new JsonPrimitive(op));
		}
	
		System.out.println("InitRec:"+resList);
		ret.add("rec", resArray);
		
		return ret;
	}
	
//	
//	private ArrayList validDirllList(String drill){
//		if(){}
//		
//		return new ArrayList<String>();
//	}
	
	private boolean isOpValid(String op,LogTable logtable){
		
		String [] ops = op.split(":");
		
		if(ops[0].equals("all")){
			return true;
		}
		else if(ops[0].equals("drill")){
			String drillBy =  logtable.dict.get(ops[1]);
			
			System.out.println("Drill By:"+drillBy+" "+" "+ops[1]+" "+logtable.selMap.get(drillBy)+" "+logtable.selMap);
			
			if(logtable.selMap.get(drillBy).equals("none")&&(logtable.parent.get(drillBy).equals("top")||!logtable.selMap.get(logtable.parent.get(drillBy)).equals("none"))){
				return true;
			}
			else{
				
				return false;
			}
			
			
		}
		else if(ops[0].equals("roll")){
			String rollBy = logtable.dict.get(ops[1]);
			if(logtable.selMap.get(rollBy).equals("none")){
				return false;
			}
			else{
				return true;
			}
		}
		else if(ops[0].equals("slice")){
			
			String sliceBy = logtable.dict.get(ops[1]);
			
			System.out.println("Slice By:"+sliceBy+" "+ops[1]);
			
			if(!logtable.selMap.get(sliceBy).equals(ops[2]) &&  (logtable.parent.get(sliceBy).equals("top")|| !logtable.selMap.get(logtable.parent.get(sliceBy)).equals("none"))){
				
				//String key = "";
				ArrayList <String> list = null;
				
				if(sliceBy.equals(Name.level1)){
					
					String level0Sel = logtable.selMap.get(Name.level0);
					String key = Name.level0+":"+level0Sel;
					list = logtable.relationMap.get(key);
					
					if(!list.contains(ops[2])){
						return false;
					}
				}
				else if(sliceBy.equals(Name.level2)){
					
					String level0Sel = logtable.selMap.get(Name.level0);
					String level1Sel = logtable.selMap.get(Name.level1);
					String key = Name.level0+":"+level0Sel+":"+Name.level1+":"+level1Sel;
					list = logtable.relationMap.get(key);

					if(!list.contains(ops[2])){
						return false;
					}
					
				}
				else if(sliceBy.equals(Name.city)){
					
					String countrySel = logtable.selMap.get(Name.country);
					String key = Name.country + ":" + logtable.selMap.get(Name.country);
					list = logtable.relationMap.get(key);
				
					if(!list.contains(ops[2])){
						return false;
					}
				}
				else if(sliceBy.equals(Name.month)){
					
					String yearSel = logtable.selMap.get(Name.year);
					String key = Name.year + ":" + logtable.selMap.get(Name.year);
					list = logtable.relationMap.get(key);
				
					if(!list.contains(ops[2])){
						return false;
					}
				}
				else if(sliceBy.equals(Name.day)){
					
					String yearSel = logtable.selMap.get(Name.year);
					String monthSel = logtable.selMap.get(Name.month);
				
					String key = Name.year + ":" + logtable.selMap.get(Name.year)+":"+Name.month+":"+logtable.selMap.get(Name.month);
					list = logtable.relationMap.get(key);
					
					if(!list.contains(ops[2])){
						return false;
					}
					
				}
				
			
				
				
				//if(logtable.relationMap){}
				
				return true;
			}
			
		}
		return false;
	}
	
	private ArrayList <String> modifyReclist(ArrayList <String> recList,LogTable logtable){
		
		ArrayList<String> retList = new ArrayList<String>();
		
		for(String p:recList){
			
			String [] ops =  p.split(":");
			String mp = "";
			
			if(ops[0].equals("slice")){
				mp = "Slice by "+logtable.dict.get(ops[1])+"="+"\""+ops[2]+"\"";
			}
			else if(ops[0].equals("drill")){
				mp = "Drill by "+"\""+logtable.dict.get(ops[1])+"\"";
			}
			else if(ops[0].equals("roll")){
				mp = "Roll by "+"\""+logtable.dict.get(ops[1])+"\"";
			}
			else if(ops[0].equals("all")){
				mp = "Reset";
			}
			retList.add(mp);
			
		}
		
		return retList;
	}
	
	public JsonObject recQueries(int k,String operator,LogTable logtable){
		
		ArrayList <String> resList = new ArrayList<String>();
		//Map <String,String> selMap = logtable.selMap; 
		
		
		Map <String,Double> pMap = new HashMap<String,Double>();
		
		JsonArray resArray = new JsonArray();
		
		if(logtable.pairMap.containsKey(operator)){
			
			Map<String,Integer> innerMap = logtable.pairMap.get(operator);
			
			Double totOpCnt = Double.valueOf(logtable.opCount);
			Double totPairCnt = Double.valueOf(logtable.pairCount);
			Double opCnt = Double.valueOf(logtable.opCountMap.get(operator));
			
			for(Map.Entry<String, Integer> entry : innerMap.entrySet()){
				
				if(isOpValid(entry.getKey(),logtable)==false){
					System.out.println("Invalid:"+entry.getKey());
					continue;
				}
				
				Double pairCnt =Double.valueOf(entry.getValue());
				//pMap.put(entry.getKey(), );
				Double p = (pairCnt/totPairCnt)/(opCnt/totOpCnt);

				pMap.put(entry.getKey(), p);
				
				System.out.println(entry.getKey()+":"+p);
			
				if(resList.size()<k){
					resList.add(entry.getKey());
				}
				else{
					for(int i= 0;i<resList.size();i++){
						if(pMap.get(resList.get(i))<p){
							resList.set(i, entry.getKey());
							break;
						}
					}
				}
			
				
			}
		
		}
		
		Gson gson = new Gson();
		JsonObject ret = new JsonObject();
		
		JsonArray resarray = new JsonArray();
		
		resList = modifyReclist(resList,logtable);	
		
		for(String res:resList){
			JsonPrimitive resp = new JsonPrimitive(res);
			resarray.add(resp);
		}
		
		System.out.println("recList:"+resList);
		
		 ret.add("rec", resarray);
	
		
		
		return ret;
		
		
	}

}
